package com.keta.foundation.interceptor;

import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import com.keta.foundation.entity.LogInfo;
import com.keta.foundation.log.Log;
import com.keta.foundation.log.LogUtil;
import com.keta.foundation.service.LogInfoService;
import com.keta.foundation.shiro.ShiroUser;

public class LogInterceptor extends HandlerInterceptorAdapter {

	@Autowired
	private LogInfoService logInfoService;

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		LogUtil.putRequest(request);

		return super.preHandle(request, response, handler);
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {

		if (!(handler instanceof HandlerMethod)) {
			return;
		}
		HandlerMethod handlerMethod = (HandlerMethod) handler;
		Method method = handlerMethod.getMethod();
		Log log = method.getAnnotation(Log.class);

		if (log != null) {

			String message = log.message();
			MessageFormat mFormat = new MessageFormat(message);

			Object[] objects = LogUtil.getArgs();

			final String result = mFormat.format(objects);

			if (!StringUtils.isNotBlank(result)) {
				return;
			}

			// 开启一个线程来写入日志，避免入库操作造成阻塞渲染视图
			new Thread(new Runnable() {

				@Override
				public void run() {

					ShiroUser shiroUser = (ShiroUser) SecurityUtils.getSubject().getPrincipal();

					LogInfo logInfo = new LogInfo();
					logInfo.setIpAddress(shiroUser.getIpAddress());
					logInfo.setUsername(shiroUser.getLoginName());
					logInfo.setMessage(result);
					logInfo.setCreateTime(new Date());
					logInfoService.save(logInfo);
				}
			}).start();
		}
		
		super.postHandle(request, response, handler, modelAndView);
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {

		LogUtil.romeveRequest();

		super.afterCompletion(request, response, handler, ex);
	}
}
